﻿using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Transactions;
using Newtonsoft.Json;
using T.ServiceComponent.Database.Service;
using T.FAS.Runtime.DataModel.Dao;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.ServiceComponent.Error;
using T.FAS.Runtime.Base.Entity;

namespace T.FAS.Runtime.DataModel.Dao
{
    public class EntityObjectLogic 
    {
        private readonly EntityObjectELBDao _entityObjectDao = new EntityObjectELBDao();
        
        public const string MetaDataID = DataModelConst.EOMetaType;
        public const string MetaDataName = "实体对象";

        #region 查询元数据信息
        public EntityObject GetEntityObjectByID(string eoId)
        {
            var eo = _entityObjectDao.GetEntityObjectByID(eoId);
            //InitializeMetaData(eo);
            return eo;
        }

        public List<EntityObject> GetEntityObjects(Dictionary<string, string> filter)
        {
            var EOs = _entityObjectDao.GetEntityObjects(filter);
            if(EOs != null && EOs.Count > 0)
            {
                EOs.ForEach(e => PackagingDependencyMetaData(e));
            }
            return EOs;
        }

        public void PackagingDependencyMetaData(EntityObject entityObject, HashSet<string> eoIdCache = null, int depth = 0)
        {
            if (entityObject == null)
                return;
            if (eoIdCache == null)
                eoIdCache = new HashSet<string>();

            if (entityObject.EntityObjectAttributes != null && entityObject.EntityObjectAttributes.Count > 0)
            {
                foreach (var attr in entityObject.EntityObjectAttributes)
                {
                    if (!string.IsNullOrEmpty(attr.RelatedEntityObjectID))
                    {
                        attr.SubEntity = _entityObjectDao.GetEntityObjectByID(attr.RelatedEntityObjectID);
                        //避免环路，cacheKey为EO.ID与外键EO属性 算作一条路径
                        var cacheKey = entityObject.ID + attr.Code;
                        if (!eoIdCache.Contains(cacheKey))
                            eoIdCache.Add(cacheKey);
                        else
                        {
                            continue;
                        }
                        PackagingDependencyMetaData(attr.SubEntity, eoIdCache, depth + 1);
                    }
                }
            }
        }
        #endregion

        #region 新增
        public void SaveEntityObject(EntityObject entityObject)
        {
            EntityTools.FillMainObjectFieldForAdd(entityObject, entityObject);
            //处理Source，给系统默认字段赋值
            if (entityObject.EntityObjectAttributes != null && entityObject.EntityObjectAttributes.Count > 0)
            {
                entityObject.EntityObjectAttributes.ForEach(source =>
                {
                    source.EntityObjectID = entityObject.ID;
                    EntityTools.FillSystemFiledForAdd(source, entityObject);
                });
            }

            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
                {
                    _entityObjectDao.SaveEntityObject(entityObject);
                    scope.Complete();
                }
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.EO.CreateError, $"{MetaDataName}元数据保存失败！ID:{entityObject.ID},Code:{entityObject.Code},Msg:{e.Message}", e);
            }
        }
        #endregion

        #region 删除
        /// <summary>
        /// 删除EO
        /// </summary>
        /// <param name="eoId"></param>
        public void DeleteEntityObject(string eoId)
        {
            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
                {
                    _entityObjectDao.DeleteEntityObject(eoId);
                    scope.Complete();
                }
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.EO.DeleteError, $"{MetaDataName}元数据删除失败！ID:{eoId},Msg:{e.Message}", e);
            }
        }

        #endregion
    }
}
